package org.awa.demo.opencv.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.awa.demo.opencv.demo.FaceDetection;
import org.awa.demo.opencv.entity.GeoPolygonBuildEntity;
import org.awa.demo.opencv.entity.GeoPolygonRoadEntity;
import org.awa.demo.opencv.entity.SoundCalBuildLogEntity;
import org.awa.demo.opencv.request.CalBuildRequest;
import org.awa.demo.opencv.request.CalRequest;
import org.awa.demo.opencv.request.TrafficAddRequest;
import org.awa.demo.opencv.request.UploadLostRequest;
import org.awa.demo.opencv.service.IGisService;
import org.awa.demo.opencv.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xxf
 */
@Slf4j
@RestController
@RequestMapping("/gis")
public class GisController {

    @Autowired
    private IGisService gisService;

//    /**
//     * 导入shape数据
//     * @return
//     */
//    @PostMapping("/shape/upload")
//    @ResponseBody
//    public R<Object> send(@RequestParam("file") MultipartFile file, UploadLostRequest request) {
//        log.info("进入[导入shape数据]文件上传...");
//        try {
//            if (file.isEmpty()) {
//                return R.fail("文件为空,请选择你的文件上传");
//            }
//
//            if(request.getType() == 0){
//                List<GeoPolygonBuildEntity> dataList = gisService.importGisBuilding(file);
//                gisService.saveGeoPolygonBuildList(dataList);
//            }else{
//                List<GeoPolygonRoadEntity> dataList = gisService.importGisRoad(file);
//                gisService.saveGeoPolygonRoadList(dataList);
//            }
//
//            return R.ok();
//        } catch (Exception e) {
//            e.printStackTrace();
//            log.error("lost data exception:"+e.toString(),e);
//            return R.fail("fail:"+e.toString());
//        }
//    }

    /**
     * 添加交通数据
     *
     * @param request
     * @param bindingResult
     * @return
     * @throws Exception
     */
    @PostMapping("/traffic/add")
    public R<Object> addTraffic(@RequestBody @Valid TrafficAddRequest request, BindingResult bindingResult) throws Exception{
        log.info("进入[添加交通数据] - "+ request);
        if(bindingResult.hasFieldErrors()){
            return R.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        gisService.addTraffic(request);
        return R.ok();
    }

    /**
     * 计算
     *
     * 实验范围：
     * POLYGON((40515388.1 3354831.0,40515842.3 3354817.2,40515919.8 3354460.0,40515343.8 3354340.9,40515388.1 3354831.0))
     *
     * 导入shape数据
     * @return
     */
    @PostMapping("/cal")
    @ResponseBody
    public R<Object> cal(@RequestBody @Valid CalRequest calRequest, BindingResult bindingResult) {
        log.info("进入[计算] - "+ calRequest);
        if(bindingResult.hasFieldErrors()){
            return R.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        Map<Integer, SoundCalBuildLogEntity> buildLogMap = gisService.cal(calRequest);
        gisService.buildGeoJson(buildLogMap);
        return R.ok();
    }

    /**
     * 计算
     *
     * 实验范围：
     * POLYGON((40515388.1 3354831.0,40515842.3 3354817.2,40515919.8 3354460.0,40515343.8 3354340.9,40515388.1 3354831.0))
     *
     * 导入shape数据
     * @return
     */
    @PostMapping("/cal/build")
    @ResponseBody
    public R<Object> calBuild(@RequestBody @Valid CalBuildRequest calBuildRequest, BindingResult bindingResult) {
        log.info("进入[计算-建筑物] - "+ calBuildRequest);
        if(bindingResult.hasFieldErrors()){
            return R.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SoundCalBuildLogEntity entity = gisService.calBuild(calBuildRequest);
        gisService.buildGeoJsonSingle(entity);
        return R.ok();
    }



    /**
     * 获取geojson文件
     *
     * @return
     * @throws Exception
     */
    @GetMapping("/geojson")
    public void getGeojson(HttpServletResponse response){
        log.info("进入[获取建筑geojson文件]");

        try{
            File file = new File(FaceDetection.GEOJSON_PATH);
            if(!file.exists()){
                log.error("has no geojson file");
            }
            InputStream is = new BufferedInputStream(new FileInputStream(file));
            outputFile(response,is,file.getName(),"application/json");
        }catch (Exception e){
            e.printStackTrace();
            log.error("png download get exception:{}",e.toString());
        }
    }

    /**
     * 获取geojson文件
     *
     * @param path
     * @return
     * @throws Exception
     */
    @GetMapping("/sound/png")
    public void getPng(HttpServletResponse response,@RequestParam("path") String path){
        log.info("进入[获取Png图片] - "+ path);
        if(StringUtils.isEmpty(path)){
            log.error("file object get exception:path is empty");
        }

        try{
            String filePath = FaceDetection.FILE_UPLOAD_PREF + path;
            File file = new File(filePath);
            InputStream is = new BufferedInputStream(new FileInputStream(file));
            outputFile(response,is,file.getName(),"image/png");
        }catch (Exception e){
            e.printStackTrace();
            log.error("png download get exception:{},{}",e.toString(),path);
        }
    }

    /**
     * 文件下载
     *  @param response
     */
    public void outputFile(HttpServletResponse response, InputStream inputStream,String fileName,String contentType) throws Exception {
        OutputStream outs = response.getOutputStream();// 获取文件输出IO流
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        int bytesRead = 0;
        byte[] buffer = new byte[1024];
        // 开始向网络传输文件流
        while ((bytesRead = inputStream.read(buffer, 0, 1024)) != -1) {
            outs.write(buffer, 0, bytesRead);
        }
        outs.flush();// 这里一定要调用flush()方法
        inputStream.close();
        outs.close();
    }


}
